package org.example;


/*
 *  示例1：[a,b]=[c,d]
 *  示例2: [a, b=c, [d, e=c]]
 *
 *  语法:
 *  grammar NestedNameList;
 *  stat     : list EOF | assign EOF ;
 *  assign   : list '=' list ;
 *  list     : '[' elements ']' ;
 *  elements : element (',' element)* ;
 *  element  : NAME '=' NAME
 *           | NAME
 *           | list
 *           ;
 *
 *  NAME     : ('a'..'z' | 'A'..'Z')+ ;   // NAME含有至少一个字母
 * */
public class ListParser extends Parser {
    public ListParser(Lexer input) {
        super(input);
    }

    public void stat() {
        if (speculate_stat_alt1()) {
            list();
        } else if (speculate_stat_alt2()) {
            assign();
        } else {
            throw new NoViableAltException("期望为：stat ，但是当前为：" + LT(1));
        }
    }

    // 尝试匹配：list EOF
    private boolean speculate_stat_alt1() {
        var success = true;
        mark();
        try {
            list();
            match(ListLexer.EOF_TYPE);
        } catch (RecognitionException e) {
            success = false;
        }
        release();
        return success;
    }

    // 尝试匹配：assign EOF
    private boolean speculate_stat_alt2() {
        var success = true;
        mark();
        try {
            assign();
            match(ListLexer.EOF_TYPE);
        } catch (RecognitionException e) {
            success = false;
        }
        release();
        return success;
    }

    public void assign() {
        list();
        match(ListLexer.EQUAL);
        list();
    }

    public void list() {
        match(ListLexer.LBRACK);
        elements();
        match(ListLexer.RBRACK);
    }

    public void elements() {
        element();
        while (LA(1) == ListLexer.COMMA) {
            match(ListLexer.COMMA);
            element();
        }
    }

    public void element() {
        if (LA(1) == ListLexer.NAME && LA(2) == ListLexer.EQUAL) {
            match(ListLexer.NAME);
            match(ListLexer.EQUAL);
            match(ListLexer.NAME);
        } else if (LA(1) == ListLexer.NAME) {
            match(ListLexer.NAME);
        } else if (LA(1) == ListLexer.LBRACK) {
            list();
        } else {
            throw new Error("期望输入name、name=name或list，但是输入为: " + LA(1));
        }
    }
}
